/*
 * @Author       : xh
 * @Date         : 2022-11-14 19:53:18
 * @LastEditors: y001554
 * @FileName     :
 */
import {
  defineComponent,
  toRefs,
  reactive,
  computed,
  onMounted,
  watch,
  ref,
  nextTick,
  getCurrentInstance,
  h
} from 'vue'
// import type { FormItemProps } from 'element-plus'
import { ElMessage, ElForm } from 'element-plus'

import {
  FOOTER_OPTIONS,
  IPROPS,
  TOOGLE_NUM,
  CUSTOMER_PROPS
} from './composables/setting'
import { deepMerge, firstToUpper1 } from '../../../utils'
import {
  Items,
  componentProps,
  ComponentProps,
  FormObj,
  OptionObj,
  ItemData
} from './type'
import './index.scss'
import useRender from './composables/use-render'
import { typeOf } from '@@/utils/components/tools'

const PROMISE_WHITE = ['radio', 'checkbox', 'select']

export default defineComponent({
  name: 'M-Form',
  props: componentProps,
  emits: ['update:modelValue', 'reset', 'submit'],
  setup(props: ComponentProps, context) {
    // console.log(123, renderUpload)
    const currentInstance = getCurrentInstance()

    // console.log(
    //   'mixinx',
    //   mixins?.appContext.config.globalProperties?.$expandHooks
    // )
    const { slots, emit, attrs, expose } = context
    let { formModel, customerProps, modelValue } = props
    // console.log('customerProps', slots)
    customerProps = deepMerge(CUSTOMER_PROPS, customerProps)

    const formRef = ref<InstanceType<typeof ElForm>>()
    const loading = ref<boolean>(true)
    const form = ref<FormObj>({})

    const {
      renderNumber,
      renderRadio,
      renderCheckbox,
      renderDatePicker,
      renderSwitch,
      renderInput,
      renderSelect,
      renderTimePicker,
      renderTimeSelect
    } = useRender(context, form)

    const initDefaultIProps = (it: Items) => {
      const iw = ['input', 'text', 'number']
      const isTextType = iw.includes(it.type)

      return {
        placeholder: `请${isTextType ? '输入' : '选择'}${it.label}`,
        'start-placeholder': '请选择开始时间',
        'end-placeholder': '请选择结束时间'
      }
    }

    //@注释
    //@name:过滤表单对象
    //@params:
    //@des:
    const loadForm = async (data: ItemData): Promise<ItemData> => {
      loading.value = true
      const plist: Array<any> = []
      try {
        data.length &&
          data.map((it: Items) => {
            const k = it.type
            it.iProps = {
              ...(IPROPS[k] || IPROPS.default),
              ...initDefaultIProps(it),
              ...it.iProps
            }

            if (PROMISE_WHITE.includes(it.type)) {
              it.cacheKey = '' //储存第一次的搜索关键字
              //首次自动加载
              if (it.autoLoadOptions && it.optionsPromise) {
                const promise = new Promise(async (rol, rej) => {
                  const res = it.optionsPromise && (await it.optionsPromise(it))
                  it.options = [...res]
                  rol([...res])
                })
                promise && plist.push(promise)
              }
            }
          })

        await Promise.all([...plist])
        loading.value = false
        return data
      } catch (error) {
        loading.value = false
        console.log('error', error)
        return []
      }
    }

    //@注释
    //@name:
    //@params:
    //@des:初始化表单项
    const initForm = async (isReset: boolean = false): Promise<any> => {
      const res: FormObj = modelValue

      if (!formModel) {
        console.error('请务必传入表单项配置')
        return {}
      }

      const loadFormData = await loadForm(formModel)

      // loading.value = false
      loadFormData.map((it: Items) => {
        if (it.value) {
          res[it.kayName] = it.value
        } else if (isReset) {
          //设置local默值
          delete res[it.kayName]
        }

        // form.value[it.kayName] = res[it.kayName]
      })
      form.value = modelValue
      // return null
    }

    //@注释
    //@name:渲染节点
    //@params:
    //@des:
    const renderNodes = () => {
      return formModel.map((item: Items, index: number) => {
        let canshow =
          item.show === undefined
            ? true
            : typeof item.show === 'function'
            ? item.show(item)
            : item.show

        return canshow ? (
          customerProps.col ? (
            <el-col {...customerProps.col} {...item.col}>
              <div class={['ylui-form-node']}>
                <el-form-item
                  {...item.fProps}
                  label={
                    customerProps.showLabel && item.label ? item.label : ''
                  }
                  disabled={item.disabled}
                  prop={item.kayName}
                  v-slots={{
                    label: () => renderLabel(item)
                  }}
                >
                  {renderItems(item)}
                </el-form-item>
              </div>
            </el-col>
          ) : (
            <div class={['ylui-form-node']}>
              <el-form-item
                {...item.fProps}
                label={customerProps.showLabel && item.label ? item.label : ''}
                disabled={item.disabled}
                prop={item.kayName}
                v-slots={{
                  label: () => renderLabel(item)
                }}
              >
                {renderItems(item)}
              </el-form-item>
            </div>
          )
        ) : null
      })
    }

    //@注释
    //@name:玄滩自定义的label
    //@params:
    const renderLabel = (item: Items): any => {
      return item.labelAfter && typeof item.labelAfter === 'function' ? (
        <div class="ylui-form-label">
          <span>{item.label}</span>
          {item.labelAfter(h, item)}
        </div>
      ) : null
    }

    //@注释
    //@name:节点类型映射
    //@params:
    //@des:
    const renderItems = (item: Items): any => {
      // console.log('123', item)
      switch (item.type) {
        case 'number':
          return renderNumber(item)
        case 'radio':
          return renderRadio(item)
        case 'checkbox':
          return renderCheckbox(item)
        case 'select':
          return renderSelect(item)
        case 'datePicker':
          return renderDatePicker(item)
        case 'switch':
          return renderSwitch(item)
        case 'timePicker':
          return renderTimePicker(item)
        case 'timeSelect ':
          return renderTimeSelect(item)
        default:
          //自定义扩展组件
          const useExpand =
            currentInstance?.appContext.config.globalProperties?.$expandHooks

          const expandHooks = useExpand ? useExpand(context, form) : {}
          const hookName = `render${firstToUpper1(item.type)}`
          // debugger
          if (expandHooks[hookName]) {
            return expandHooks[hookName](item)
          } else {
            return renderInput(item)
          }
      }
    }

    // ============================== 对外暴露方法======================================
    const sure = (): void => {
      try {
        formRef.value &&
          formRef.value.validate((res: boolean, err: any) => {
            if (res) {
              emit('submit', form.value)
            } else {
              const errs = err && Object.keys(err)
              const k = errs ? errs[0] : ''
              const m = err[k][0]
              m && k && ElMessage.warning(m)
            }
          })
      } catch (error) {
        console.error('提交函数错误', error)
      }
    }
    const reset = async (): Promise<void> => {
      await initForm(true)
      emit('reset', form.value)
      // debugger
    }

    //手动 ref方法
    const setValue = (data: Object): void => {
      nextTick(() => {
        form.value = data
      })
    }
    const getValue = (): Object => {
      return form.value
    }

    expose({ sure, reset, setValue, getValue })

    onMounted(async () => {
      initForm()
    })
    return () => {
      return (
        <el-form
          model={form}
          label-width="80px"
          {...attrs}
          v-loading={loading.value}
          style={{ opacity: `${!loading.value ? 1 : 0.5}` }}
          class={`ylui-form-${
            customerProps.row || !props.inline ? 'block' : 'inline'
          }`}
          ref={formRef}
        >
          {/* 表单内容 */}
          {customerProps.row ? (
            <el-row gutter={10} {...customerProps.row}>
              {formModel && renderNodes()}
            </el-row>
          ) : (
            formModel && renderNodes()
          )}

          {/* <div style="flex:1"></div> */}
          {/* 表单按钮模块 */}
          {slots.formFooter
            ? slots.formFooter()
            : customerProps.actionShow && (
                <footer class="ylui-form__footer">
                  {customerProps.footerOptions?.submitShow && (
                    <el-button type="primary" onClick={sure}>
                      {customerProps.footerOptions?.submitText || '提交'}
                    </el-button>
                  )}
                  {customerProps.footerOptions?.resetShow && (
                    <el-button type="default" onClick={reset}>
                      {customerProps.footerOptions?.resetText || '重置'}
                    </el-button>
                  )}
                </footer>
              )}
        </el-form>
      )
    }
  }
})
